#include "include/bmp280.h"
#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "esp_log.h"
#include "esp_err.h"
#include "user_iic.h"

static uint16_t		dig_T1;
static int16_t 		dig_T2;
static int16_t 		dig_T3;
static uint16_t 	dig_P1;
static int16_t 		dig_P2;
static int16_t 		dig_P3;
static int16_t 		dig_P4;
static int16_t 		dig_P5;
static int16_t 		dig_P6;
static int16_t 		dig_P7;
static int16_t 		dig_P8;
static int16_t 		dig_P9;

/* 描述：向BMP280写入8bit数据
 * 参数cmd：BMP280指令
 * 返回值：成功返回ESP_OK                     */
esp_err_t BMP280_Write_Data(uint8_t addr, uint8_t *data, uint8_t data_len)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, BMP280_ADDRESS|WRITE_BIT, ACK_CHECK_EN);
    i2c_master_write_byte(cmd, addr, ACK_CHECK_EN);
    i2c_master_write(cmd, data, data_len, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(I2C_EXAMPLE_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);

    return ret;
}


/* 描述：从BMP280读取数据
 * 参数data_len：读取多少个字节数据
 * 参数data_arr：读取的数据存放在一个数组里
 * 返回值：读取成功返回ESP_OK
*/
static esp_err_t BMP280_Read_Data(uint8_t addr, uint8_t* data_arr, uint8_t data_len)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, BMP280_ADDRESS|WRITE_BIT, ACK_CHECK_EN);
    i2c_master_write_byte(cmd, addr, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(I2C_EXAMPLE_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);

    if (ret != ESP_OK)
    {
        return ret;
    }

    cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, BMP280_ADDRESS|READ_BIT, ACK_CHECK_EN);
    i2c_master_read(cmd, data_arr, data_len, LAST_NACK_VAL);
    i2c_master_stop(cmd);
    ret = i2c_master_cmd_begin(I2C_EXAMPLE_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);

    return ret;
}

/*  软复位芯片 */
static void BMP280_chip_reset(void)
{
    uint8_t rbuf = BMX280_RESET_VALUE;
    BMP280_Write_Data(BMX280_RESET_REG, &rbuf, 1);
    vTaskDelay(100 / portTICK_RATE_MS);
}

/**
*
*/
static void BMP280_readTrim(void)
{
    uint8_t data[24]= {0};
	BMP280_Read_Data(BMP280_DIG_T1_LSB_REG, &data[0], 24);

	dig_T1 = (data[1] << 8) | data[0];
	dig_T2 = (data[3] << 8) | data[2];
	dig_T3 = (data[5] << 8) | data[4];
	dig_P1 = (data[7] << 8) | data[6];
	dig_P2 = (data[9] << 8) | data[8];
	dig_P3 = (data[11] << 8) | data[10];
	dig_P4 = (data[13] << 8) | data[12];
	dig_P5 = (data[15] << 8) | data[14];
	dig_P6 = (data[17] << 8) | data[16];
	dig_P7 = (data[19] << 8) | data[18];
	dig_P8 = (data[21] << 8) | data[20];
	dig_P9 = (data[23] << 8) | data[22];
}

long BMP280_GetValue(void)
{
	long adc_T;
	long adc_P;
	long var1, var2, t_fine, T, p;

	uint8_t data[8];
	BMP280_Read_Data(BMX280_PRESSURE_MSB_REG, &data[0], 6);

	adc_P = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
	adc_T = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);

	if(adc_P == 0)
	{
		return 0;
	}

	//Temperature
	var1 = (((double)adc_T)/16384.0-((double)dig_T1)/1024.0)*((double)dig_T2);
	var2 = ((((double)adc_T)/131072.0-((double)dig_T1)/8192.0)*(((double)adc_T)
				/131072.0-((double)dig_T1)/8192.0))*((double)dig_T3);

	t_fine = (unsigned long)(var1+var2);

	T = (var1+var2)/5120.0;

	var1 = ((double)t_fine/2.0)-64000.0;
	var2 = var1*var1*((double)dig_P6)/32768.0;
	var2 = var2 +var1*((double)dig_P5)*2.0;
	var2 = (var2/4.0)+(((double)dig_P4)*65536.0);
	var1 = (((double)dig_P3)*var1*var1/524288.0+((double)dig_P2)*var1)/524288.0;
	var1 = (1.0+var1/32768.0)*((double)dig_P1);
	p = 1048576.0-(double)adc_P;
	p = (p-(var2/4096.0))*6250.0/var1;
	var1 = ((double)dig_P9)*p*p/2147483648.0;
	var2 = p*((double)dig_P8)/32768.0;
	p = p+(var1+var2+((double)dig_P7))/16.0;

	return p;
}


void BMP280_Init(void)
{


	BMP280_chip_reset();
	/*手册提到只要40ms就可以启动，可根据时间情况加减 */
	vTaskDelay(40 / portTICK_RATE_MS);

	uint8_t data_ID;
	BMP280_Read_Data(BMX280_CHIPID_REG, &data_ID, 1);
	/* 读取BMP280的SerialNumber值 */
	if(data_ID == BMP280_CHIP_ID)
		printf("Read BMP280_SerialNumber 0k: 0x%x \n",data_ID);
	else
		printf("Read BMP280_SerialNumber err: 0x%x \n",data_ID);

	uint8_t data = 0xFF;
	BMP280_Write_Data(BMX280_CTRLMEAS_REG, &data, 1);
	data = 0x00;
	BMP280_Write_Data(BMX280_CONFIG_REG, &data, 1);

	BMP280_readTrim();
}



